package com.suray.wcs.service.pojo.rgv.rgv.protocol.message;

import com.suray.basic.wcs.utils.LoggerUtil;
import com.suray.basic.wcs.utils.typedef.DWord;
import com.suray.basic.wcs.utils.typedef.Word;
import com.suray.basic.wcs.utils.typedef.Byte;
import com.suray.commin.core.utils.SpringContextHolder;
import com.suray.wcs.res.enums.Order;
import com.suray.wcs.service.enums.CodeType;
import com.suray.commin.exception.OrderExecuteException;
import com.suray.wcs.service.pojo.Rgv;
import com.suray.wcs.service.pojo.rgv.action.RgvCommandAction;
import com.suray.wcs.service.pojo.rgv.action.util.RgvActionStatus;
import com.suray.wcs.service.pojo.rgv.rgv.protocol.base.RgvRecMessage;
import com.suray.wcs.service.pojo.rgv.rgv.protocol.util.RgvMessageType;
import com.suray.wcs.service.system.service.impl.CodeDBServiceImpl;

import java.io.IOException;
import java.util.Arrays;

public class RgvCommandRecMessage extends RgvRecMessage {

    private final static CodeDBServiceImpl codeDBService = SpringContextHolder.getBean(CodeDBServiceImpl.class);

    private boolean plcResult = false;

    public RgvCommandRecMessage(Rgv rgv) {
        super(rgv, "指令接收");

        baseDatas.add(new Word("头帧", "取值0x02FD"));
        baseDatas.add(new Byte("设备ID", "取值范围：0-255， 小车对应设备号"));
        baseDatas.add(new Byte("life", "0-255"));
        baseDatas.add(new Byte("报文类型", "0:心跳，1：整体任务，2：指令，3：调试指令"));
        baseDatas.add(new Byte("任务/指令 编号", "1-255"));
        baseDatas.add(new Word("执行结果", "1：进行中，2.执行完成"));
        if (rgv.isBA()){
            rgv.setBA(false);
            plcResult = true;
            baseDatas.add(new DWord("执行结果参数high", "高位在前低位在后（例：速度值为0x4b0;填写在该位置为： 00 00 04 b0）"));
            baseDatas.add(new DWord("执行结果参数low", "高位在前低位在后（例：速度值为0x4b0;填写在该位置为： 00 00 04 b0）"));
        }else {
            baseDatas.add(new DWord("执行结果参数", "高位在前低位在后（例：速度值为0x4b0;填写在该位置为： 00 00 04 b0）"));
        }
        baseDatas.add(new Word("报文长度", "整条报文的长度"));
        baseDatas.add(new Word("校验位", "CRC（循环冗余校验；低位在前，高位在后），采用crc16_modbus"));
        baseDatas.add(new Word("尾帧", "0x3FC"));
    }

    public int getCmdNo() {
        return getValue("任务/指令 编号");
    }

    public int getResult() {
        return getValue("执行结果");
    }

    public long getRFIDResultParam() {
        long high = getValue("执行结果参数high");
        long low = getValue("执行结果参数low");
        return high << (4 * 8) + low;
    }

    public int getResultParam() {
        return getValue("执行结果参数");
    }

    public int getMessageLength() {
        return getValue("报文长度");
    }

    @Override
    public boolean checkMessage(byte[] recData, RgvMessageType rgvMessageType, Integer sendLife) throws IOException {
        boolean result = super.checkMessage(recData, rgvMessageType, sendLife);

        int messageLength = getMessageLength();
        if (recData.length != messageLength) {
            throw new RuntimeException("解析的报文长度与接收的实际长度不一致:" + Arrays.toString(recData));
        }

        if (result) {
            analyzeMessage();
        }

        return result;
    }

    private void analyzeMessage() {
        // 1. 接受成功 2. 接受重复
        int result = getResult();
        if (result == 1 || result == 2) {
            freshCommandStatus(getRgv(), result);
        } else {
            getRgv().getCmdAction().initStatus();
            throw new OrderExecuteException(getRgv().getRgvDB().getRgvNo(), getResult(), codeDBService.getCodeDescByFault(getResult(), CodeType.RES_ERROR_CODE));
        }
    }

    private void freshCommandStatus(Rgv rgv, int result) {
        Order order = rgv.getCmdAction().getActionType();
        RgvCommandAction cmdAction = rgv.getCmdAction();
        // 异步指令
        if (order.getOrderType().equals(1)) {
            cmdAction.setActionStatus(RgvActionStatus.RGV_DOING_ACTION);
        } else if (order.getOrderType().equals(0)) {
            //同步指令
            cmdAction.setActionStatus(RgvActionStatus.RGV_END_ACTION);
        } else {
            throw new RuntimeException("指令类型错误：" + order);
        }
        LoggerUtil.debug("指令:" + order.getOrderDescribe() + ",收到的指令结果:" + result, this.getClass());
    }

    @Override
    public Integer getMessageLife() {
        return getValue("life");
    }

    @Override
    public Integer getMessageType() {
        return getValue("报文类型");
    }
}
